#include <conio.h>
#include <stdio.h>
#include <malloc.h>
#include <time.h>
#include <stdlib.h>
#include <windows.h>
struct node
{
	int x;
	int y;
	struct node *next;
};

node *init(int length);					//初始化蛇
void print(int a[15][30],node *head);	//输出函数
void food(node *head);					//食物产生函数
void move(node *head);					//移动函数
bool dead(node *head);					//判断死亡函数

int food_x=0,food_y=0;
int food_flag = 0;
int target = 2;

void GotoXY(int x,int y);
void Hide();

int Menu(){
	GotoXY(40,12);
	printf("欢迎来到贪吃蛇小游戏！");
	GotoXY(43,14);
	printf("1.开始游戏");
	GotoXY(43,16);
	printf("2.帮助");
	GotoXY(43,18);
	printf("3.关于");
	GotoXY(43,20);
	printf("其它任意键推出游戏");
	Hide();
	char ch;
	int result=0;
	ch=_getch();
	switch (ch) {
		case '1': result=1;break;
		case '2': result=2;break;
		case '3': result=3;break;
	}
	system("cls");
	return result;
}

void GotoXY(int x,int y){
	HANDLE hout;
	COORD cor;
	hout= GetStdHandle(STD_OUTPUT_HANDLE);
	cor.X=x;
	cor.Y=y;
	SetConsoleCursorPosition(hout,cor);
}

void Hide(){
	HANDLE hout= GetStdHandle(STD_OUTPUT_HANDLE);
	CONSOLE_CURSOR_INFO cor_info={1,0};
	SetConsoleCursorInfo(hout,&cor_info);
}

void About(){
	GotoXY(30,12);
	printf("杭州电子科技大学——程序综合设计实践案例");
	GotoXY(43,14);
	printf("贪吃蛇游戏");
	GotoXY(43,16);
	printf("按任意键返回上级菜单");
	Hide();
	char ch=_getch();
	system("cls");
}

void Help(){
	GotoXY(40,12);
	printf("w 上");
	GotoXY(40,14);
	printf("s 下");
	GotoXY(40,16);
	printf("a 左");
	GotoXY(40,18);
	printf("d 右");
	GotoXY(40,20);
	printf("撞墙结束");
	GotoXY(45,22);
	printf("按任意键返回上级菜单");
	Hide();
	char ch=_getch();
	system("cls");
}




int main(){
	int end=1,result;

	int a[15][30];
	node *head;
	head = init(2);
	while(end)
	{	
		result = Menu();
		switch (result) {
			case 1:
				while(1){
					system("cls");
					move(head);
					
					if(dead(head))
						break;
					print(a,head);
					Sleep(300);
					
				}
			case 2:
				Help();
				break;
			case 3:
				About();
				break;
			case 0:
				end=0;
		}
	
	}
	system("cls");
	printf("Game Over!!!\n");
	
}
node *init(int length)
{
	int i = 2;
	node *head;
	head = (node*)malloc(sizeof(node));//分配地址
	node *p = head;
	head->x = 1;
	head->y = 1;
	while(i <= length)
	{
		node *s;
		s = (node*)malloc(sizeof(node));
		s->x = 1;
		s->y = i;
		s->next = NULL;
		p->next = s;
		p = p->next;
		i++;
	}
	food(head);
	return head;
}

void print(int a[15][30],node *head)
{
	//0为空格，-1为墙壁#，1为蛇身*，2为蛇头@,3为食物$
	int i,j;
	node *p = head;
	for(i = 0; i < 15; i++)
	{
		for(j = 0; j < 30; j++)
		{
			if(i == 0 || j == 0 || i == 14 || j == 29)
				a[i][j] = -1;
			else
				a[i][j] = 0;
		}
	}
	while(p != NULL)
	{
		if(p->next == NULL)
			a[p->x][p->y] = 2;
		else
			a[p->x][p->y] = 1;
		p = p->next;
	}
	a[food_x][food_y] = 3;
	for(i = 0; i < 15; i++)
	{
		for(j = 0; j < 30; j++)
		{
			if(a[i][j] == -1)
				printf("#");
			if(a[i][j] == 0)
				printf(" ");
			if(a[i][j] == 1)
				printf("*");
			if(a[i][j] == 2)
				printf("@");
			if(a[i][j] == 3)
				printf("$");
		}
		printf("\n");
	}	
}

void food(node *head)
{
	node *p = head;
	srand((unsigned)time(NULL));
	food_x = rand()%12 + 1;
	food_y = rand()%27 + 1;
	while(p != NULL)
	{
		if(p->x == food_x && p->y == food_y)
		{
			food_x = rand()%12 + 1;
			food_y = rand()%27 + 1;
			p = head;
		}
		p = p->next;
	}
}

void move(node *head)
{
	
	char ch;
	if(kbhit())
	{
		ch = _getch();		
		switch (ch)
		{
			case -32: 		 
			ch = _getch(); 
			switch (ch)
			{
				case 72:if(target != 1)target = 0; break;		
				case 80:if(target != 0)target = 1; break;	
				case 77:if(target != 3)target = 2; break;		
				case 75:if(target != 2)target = 3; break;	
				default:break;
			}
		}
	}
	node *p;
	node *q = head->next;
	while(q->next != NULL)
		q = q->next;
	switch(target)
	{
		case 0:if(q->x - 1 == food_x && q->y == food_y)food_flag = 1;break;
		case 1:if(q->x + 1 == food_x && q->y == food_y)food_flag = 1;break;
		case 2:if(q->x == food_x && q->y + 1 == food_y)food_flag = 1;break;
		case 3:if(q->x == food_x && q->y - 1 == food_y)food_flag = 1;break;
	}
	if(food_flag == 1)
	{
		node *s;
		s = (node*)malloc(sizeof(node));
		s->x = food_x;
		s->y = food_y;
		s->next = NULL;
		q->next = s;
		food(head);
		food_flag = 0;
	}
	else
	{
		p = head;
		q = head->next;
		while(q != NULL)
		{
			p->x = q->x;
			p->y = q->y;
			if(q->next == NULL)
			{
				switch(target)
				{
					case 0:q->x = q->x - 1;break;
					case 1:q->x = q->x + 1;break;
					case 2:q->y = q->y + 1;break;
					case 3:q->y = q->y - 1;break;
				}
			}
			p = p->next;
			q = q->next;
			
		}
	}	
}
bool dead(node *head)
{
	node *p = head;
	while(p->next != NULL)
		p = p->next;
	if(p->x >= 14 || p->x <= 0 || p->y >= 29 || p->y <= 0)
		return true;
	node *q = head;
	while(q->next != NULL)
	{
		if(q->x == p->x && q->y == p->y)
			return true;
		q = q->next;
	}
	return false;
}

